#include "lua_f_base.h"

void stack_dump(lua_State *L)
{
    int i;
    int top = lua_gettop(L);
    printf("Stack has %d elements:\n\t", top);
    for(i = 1; i <= top; ++i){
        int type = lua_type(L, i);
        switch(type){
        case LUA_TSTRING: // strings
            printf("'%s'", lua_tostring(L, i));
            break;

        case LUA_TBOOLEAN: // booleans
            printf(lua_toboolean(L, i) ? "true" : "false");
            break;

        case LUA_TNUMBER: // numbers
            //printf("%g", lua_tonumber(L, i));
            printf("%d", lua_tointeger(L, i));
            break;
        default: // other values
            printf("%s", lua_typename(L, lua_type(L, i)));
            break;
        }

        printf("\t");
    }
    printf("\n");
}

// table = {func = func_name, args=..., nresults = n}
int call_lua_func(lua_State *L)
{
	uint8_t has_args = 0;
	int nresults = 0;

	printf("enter %s()\n", __func__);
	if (lua_gettop(L) <= 0) {
		DBG("invalid args\n");
		return -1;
	}
	stack_dump(L);

	// 1. get func member
	lua_getfield(L, -1, "func");
	if (lua_type(L, -1) == LUA_TNIL) {
		DBG("no func member\n");
		return -1;
	}
	
	// 2. get args member
	lua_getfield(L, -2, "args");
	if (lua_type(L, -1) == LUA_TNIL) {
		DBG("no args member\n");
		lua_pop(L, 1);
	}
	else
		has_args = 1;

	// 3. get nresults member
	if (has_args)
	    lua_getfield(L, -3, "nresults");
	else
	    lua_getfield(L, -2, "nresults");
	    
	if (lua_type(L, -1) == LUA_TNIL)
		DBG("no nresults member\n");
	else
		nresults = luaL_optinteger(L, -1, 0);
	lua_pop(L, 1);

	if (has_args)
		lua_call(L, 1, nresults);
	else
		lua_call(L, 0, nresults);
	return 0;
}
